/*
 * Created by BAC IT Deustche Bank
 * User: Sergio Vasquez
 * Date: 6/2/2009
 * Time: 12:52 PM
 * 
 * Description:
 * 
 */
using System;
using System.Collections.Generic;
using System.Data;

using IScheduler.Core.Persistence.Base;
using IScheduler.Core.Schedule;
using IScheduler.Core.Schedule.Plan;
using IScheduler.Core.Schedule.Task;
using System.Reflection;

namespace IScheduler.Core.Persistence
{
	/// <summary>
	/// Description of ScheduleMonitorData.
	/// </summary
	
	public class ScheduleMonitorData : DataAccessLayer
	{
		/// <summary>
		/// Test database connection in case any problem the 
		/// application will be setup to work offline.
		/// </summary>
		/// <returns></returns>
		public bool TestDatabaseConnection()
		{
			try 
			{
				//using (DataAccessLayer dal = new DataAccessLayer())
	            //{
					//The DataAccessLayer object opens the connection in before use it.
	            //    return true;
	            //}
				//The DataAccessLayer object opens the connection in before use it.
	            return true;
			}
			catch (PersistenceException e)
			{
				throw new PersistenceException("An error occurred during testing database connection.", this.ToString(), e);
			}
		}
		
		/// <summary>
		///  Get scheduled tasks from the database.
		/// </summary>
		/// <param name="current"></param>
		/// <returns></returns>
		public IList<ScheduleTimer> GetScheduledTime()
		{
			IList<ScheduleTimer> list = null;
			
			string sqlCommand = " select " +
								" is_plan.id_plan, " +
								" is_plan.nm_plan, " +
								" is_plan.tx_dayofmonth, " +
								" is_plan.tx_month, " +
								" is_plan.tx_dayofweek, " +
								" is_plan.tx_year, " +
								" is_plan.tx_hour, " +
								" is_plan.tx_minute, " +
								" is_plan.tx_second, " +
								" is_plan.tx_millisecond, " +
								" is_plan.fl_businessday, " +
								" is_plan.fl_email, " +
								" is_plan.tx_extrainfo, " + 
								" is_task.id_task, " +
								" is_task.nm_task, " +
								" is_task.tx_assembly, " +
								" is_plan_task.fl_isconcurrent, " + 
								" is_plan_task.fl_isfaulttolerant " +
								" from is_plan_task " +
								" inner join is_plan on " +
								" (is_plan.id_plan = is_plan_task.id_plan) " +
								" inner join is_task on " +
								" (is_task.id_task = is_plan_task.id_task) " +
								" where " +
								" is_plan.fl_enabled=1 and is_task.fl_enabled=1 and is_plan_task.fl_enabled=1; ";


			
			IDbCommand command = GetCommandQuery(sqlCommand);
			
			using(IDataReader reader = command.ExecuteReader())
			{
				//check if is there any data in reader.
				if (reader != null)
				{
					list = new List<ScheduleTimer>();
					
					ScheduleTimer schedule = null;
										
					while (reader.Read())
	                {
						//ScheduleTimer -> SchedulePlan
						if (schedule == null || schedule.SchedulePlan.Id != TryParseReaderToInt(reader["id_plan"]))
						{
		            		schedule = new ScheduleTimer();
		            		schedule.IsEmail = TryParseReaderToBool(reader["fl_email"]);
		            		schedule.ExtraInfo = TryParseReaderToString(reader["tx_extrainfo"]);
		            		schedule.SchedulePlan.Id = TryParseReaderToInt(reader["id_plan"]);
		            		schedule.SchedulePlan.Name = TryParseReaderToString(reader["nm_plan"]);
		            		schedule.SchedulePlan.BusinessDay = TryParseReaderToBool(reader["fl_businessday"]);
		            		schedule.SchedulePlan.ConfigurePatternCollection(schedule.SchedulePlan.DaysOfMonth, TryParseReaderToString(reader["tx_dayofmonth"]));
		            		schedule.SchedulePlan.ConfigurePatternCollection(schedule.SchedulePlan.DaysOfWeek, TryParseReaderToString(reader["tx_dayofweek"]));
		            		schedule.SchedulePlan.ConfigurePatternCollection(schedule.SchedulePlan.Year, TryParseReaderToString(reader["tx_year"]));
		            		schedule.SchedulePlan.ConfigurePatternCollection(schedule.SchedulePlan.Months, TryParseReaderToString(reader["tx_month"]));
		            		schedule.SchedulePlan.ConfigurePatternCollection(schedule.SchedulePlan.Hours, TryParseReaderToString(reader["tx_hour"]));
		            		schedule.SchedulePlan.ConfigurePatternCollection(schedule.SchedulePlan.Minutes, TryParseReaderToString(reader["tx_minute"]));
		            		schedule.SchedulePlan.ConfigurePatternCollection(schedule.SchedulePlan.Seconds, TryParseReaderToString(reader["tx_second"]));
		            		schedule.SchedulePlan.ConfigurePatternCollection(schedule.SchedulePlan.Milliseconds, TryParseReaderToString(reader["tx_millisecond"]));

		            		list.Add(schedule);
						}
	            		
						//ScheduleTimer -> ScheduleTask
						Type type = Type.GetType(TryParseReaderToString(reader["tx_assembly"]), true);
						
						ConstructorInfo cstr = type.GetConstructor(new Type[0]);
						
						if (cstr == null)
						{
							throw new DataAccessException(string.Format("The type \"{0}\" does not have a default (parameter less) constructor.", TryParseReaderToString(reader["tx_assembly"])), this.ToString());
						}
						
						IScheduleTask task = (IScheduleTask) cstr.Invoke(new object[0]);
						task.Id = TryParseReaderToInt(reader["id_task"]);
						task.Name = TryParseReaderToString(reader["nm_task"]);
						task.IsConcurrent = TryParseReaderToBool(reader["fl_isconcurrent"]);
						task.IsFaultTolerant = TryParseReaderToBool(reader["fl_isfaulttolerant"]);

						list[list.Count-1].ScheduleTasks.Add(task);
	            	}
				}
				
			}
			
			return list;
		}
	}
}
